package com.tensai.teach.beijing.xml;

import java.io.IOException;
import java.io.Writer;

import org.apache.commons.lang3.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class WriteOutContentHandler extends DefaultHandler {

	private static final String NEWLINE = System.getProperty("line.separator");
	private static final String INDENT = "  ";

	private final Writer writer;
	private int depth = 0;

	public WriteOutContentHandler(Writer writer) {
		this.writer = writer;
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		try {
			writer.write(ch, start, length);
		} catch (IOException e) {
			throw new SAXException("Error writing out character content", e);
		}
	}

	@Override
	public void ignorableWhitespace(char[] ch, int start, int length)
			throws SAXException {
		try {
			writer.write(ch, start, length);
		} catch (IOException e) {
			throw new SAXException("Error writing out character content", e);
		}
	}

	@Override
	public void endDocument() throws SAXException {
		try {
			writer.flush();
		} catch (IOException e) {
			throw new SAXException("Error flushing character output", e);
		}
	}

	@Override
	public String toString() {
		return writer.toString();
	}

	@Override
	public void startElement(String uri, String localName, String qName,
	                         Attributes attrs) throws SAXException {
		write(NEWLINE);
		write(StringUtils.repeat(INDENT, depth));
		depth++;

		String eName = localName;

		if ("".equals(eName)) {
			eName = qName;
		}

		write("<" + eName);

		if (attrs != null) {
			for (int i = 0; i < attrs.getLength(); i++) {
				String attrName = attrs.getLocalName(i);

				if ("".equals(attrName)) {
					attrName = attrs.getQName(i);
				}

				write(NEWLINE);
				write(StringUtils.repeat(INDENT, depth));
				write(attrName);

				write("=\"");
				write(attrs.getValue(i));
				write("\"");
			}
		}

		assert attrs != null;
		if (attrs.getLength() > 0) {
			write(NEWLINE);
			write(StringUtils.repeat(INDENT, depth - 1));
		}

		write(">");
	}

	@Override
	public void endElement(String namespaceURI, String sName, String qName) throws SAXException {
		write(NEWLINE);
		depth--;
		write(StringUtils.repeat(INDENT, depth));

		String eName = sName;
		if ("".equals(eName)) {
			eName = qName;
		}
		write("</" + eName + ">");
	}

	private void write(String s) throws SAXException {
		try {
			writer.write(s);
			writer.flush();
		} catch (IOException e) {
			throw new SAXException("I/O error", e);
		}
	}
}